package FlowGraph.Nodes;

import antlr.collections.AST;
import java.util.*;

import util.Line;
import FlowGraph.FlowGraphNode;
import FlowGraph.StatementInfo.StatementInfo;

//////////////////////////////////////////////////////////////////////////
//// ForBeginNode
/**

@author Ivan Jeukens
@version v 0.1 03/10/2001
*/
public class ForBeginNode extends FlowGraphNode implements LoopHeadNode {

    public ForBeginNode(AST statement) {
        super(statement, FOR_BEGIN, 1, 2);

        _init = statement.getFirstChild();
        _condition = _init.getNextSibling();
        _iterator = _condition.getNextSibling();

        _initInfo = new StatementInfo(this, _init);
        _conditionInfo = new StatementInfo(this, _condition);
        _iteratorInfo = new StatementInfo(this, _iterator);

        _initExtractedNode = null;
        _iteExtractedNodes = new LinkedList();
    }

    ///////////////////////////////////////////////////////////////////
    ////                        public methods                     ////

    public FlowGraphNode getExitNode() {
        for(int i = 0;i < _outputEdges.size();i++) {
            FlowGraphNode node = getOutputNode(i);
            if(node.getType() == FlowGraphNode.FOR_END) {
                return node;
            }
        }
        return null;
    }

    public FlowGraphNode getContinueNode() {
        for(int i = 0;i < _outputEdges.size();i++) {
            FlowGraphNode node = getOutputNode(i);
            if(node.getType() != FlowGraphNode.FOR_END) {
                return node;
            }
        }
        return null;
    }

    public String toString() {
        return new String("for(" +  ")");
    }

    public void setForEnd(ForEndNode fe) {
        _forEnd = fe;
    }

    public ForEndNode getForEnd() {
        return _forEnd;
    }

    public AST getInit() {
        return _init;
    }

    public AST getCondition() {
        return _condition;
    }

    public AST getIterator() {
        return _iterator;
    }

    public void setConditionLine(Line l) {
        _conditionLine = l;
    }

    public Line getConditionLine() {
        return _conditionLine;
    }

    public void setEndLine(Line l) {
        _endLine = l;
    }

    public Line getEndLine() {
        return _endLine;
    }
    
    public void setAbsTreeNode(AST statement) {
        _init = statement.getFirstChild();
        _condition = _init.getNextSibling();
        _iterator = _condition.getNextSibling();
    }
    
    public StatementInfo getInitInfo() {
        return _initInfo;
    }

    public StatementInfo getConditionInfo() {
        return _conditionInfo;
    }

    public StatementInfo getIteratorInfo() {
        return _iteratorInfo;
    }

    public void setInitExtractedNode(FlowGraphNode node) {
        _initExtractedNode = node;
    }
    
    public FlowGraphNode getInitExtractedNode() {
        return _initExtractedNode;
    }

    public void addIteExtractedNode(FlowGraphNode node) {
        _iteExtractedNodes.add(node);
    }
    
    public int iteExtractedNodeSize() {
        return _iteExtractedNodes.size();
    }
    
    public FlowGraphNode getIteExtractedNode(int pos) {
        return (FlowGraphNode) _iteExtractedNodes.get(pos);
    }

    // Determina se e um loop sem corpo
    public boolean isEmptyLoop() {
        if(_outputEdges.size() != 2) return false;

        FlowGraphNode node = getOutputNode(0);
        if(node != this && node != _forEnd) return false;

        node = getOutputNode(1);
        if(node != this && node != _forEnd) return false;

        return true;
    }

    public void setIterations(int ite) {
        _iterations = ite;
    }

    public int getIterations() {
        return _iterations;
    }
    
    public void setGetWidthLoop(String varname) {
        _getWidthVarName = varname;
    }

    public boolean isGetWidthLoop() {
        return (_getWidthVarName != null);
    }
    
    public String getGetWidthLoop() {
        return _getWidthVarName;
    }
    
    ///////////////////////////////////////////////////////////////////
    ////                      private variables                    ////

    private AST _init;
    private AST _condition;
    private AST _iterator;

    private ForEndNode _forEnd;
    private Line _conditionLine;
    private Line _endLine;

    private StatementInfo _initInfo;
    private StatementInfo _conditionInfo;
    private StatementInfo _iteratorInfo;

    private FlowGraphNode _initExtractedNode;
    private LinkedList _iteExtractedNodes;
    
    private int _iterations;
    private String _getWidthVarName;
}
